package org.jsola.hr.service.impl;

import org.jsola.common.DateKit8;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.ISocDispatchEmpLessDAO;
import org.jsola.hr.dto.SocDispatchEmpLessAddDTO;
import org.jsola.hr.dto.SocDispatchEmpLessUpdateDTO;
import org.jsola.hr.dto.excel.SocDispatchEmpLessImportDTO;
import org.jsola.hr.entity.*;
import org.jsola.hr.query.SocDispatchEmpLessQuery;
import org.jsola.hr.service.*;
import org.jsola.hr.vo.SocDispatchEmpLessListVO;
import org.jsola.hr.vo.SocDispatchEmpLessVO;
import org.jsola.hr.vo.SocDispatchVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 社保派单员工表_减员
 *
 * @author zhr
 */
@Service("hrSocDispatchEmpLessServiceImpl")
public class SocDispatchEmpLessServiceImpl implements ISocDispatchEmpLessService {

    @Autowired
    private ISocDispatchEmpLessDAO socDispatchEmpLessDAO;

    @Autowired
    private ISocDispatchService socDispatchService;

    @Autowired
    private ISocProgService socProgService;

    @Autowired
    private IEmpSocInfoService empSocInfoService;

    @Autowired
    private IEmpSocDispatchService empSocDispatchService;

    @Autowired
    private ICompanyService companyService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public SocDispatchEmpLessVO save(SocDispatchEmpLessAddDTO socDispatchEmpLessAddDTO, TokenUser tokenUser) {
        // 转DO
        SocDispatchEmpLessDO socDispatchEmpLessDO = socDispatchEmpLessAddDTO.to(SocDispatchEmpLessDO.class);
        // 保存
        socDispatchEmpLessDO = save(socDispatchEmpLessDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return socDispatchEmpLessDO.to(SocDispatchEmpLessVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public SocDispatchVO batchSave(String companyId, String socDispatchId, boolean isUpdate, List<SocDispatchEmpLessImportDTO> socDispatchEmpLessImportList, String year, String month, Map<Integer, String> headMap, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(socDispatchEmpLessImportList)) {
            throw new ParamException("没有需要导入的数据,请检查");
        }

        // 新增或修改导入记录
        SocDispatchVO socDispatch = socDispatchService.addOrUpdateSocDispatch(companyId, socDispatchId, isUpdate, false, year, month, tokenUser);

        int sort = 1;
        for (SocDispatchEmpLessImportDTO socDispatchEmpLessImport : socDispatchEmpLessImportList) {
            SocDispatchEmpLessAddDTO socDispatchEmpLess = socDispatchEmpLessImport.to(SocDispatchEmpLessAddDTO.class);
            // 导入记录id和默认数据
            socDispatchEmpLess.setSocDispatchId(socDispatch.getId());
            socDispatchEmpLess.setYear(year);
            socDispatchEmpLess.setMonth(month);
            socDispatchEmpLess.setHasSend(false);
            socDispatchEmpLess.setHasReceive(false);
            socDispatchEmpLess.setStatus(0);
            socDispatchEmpLess.setCompanyId(companyId);
            socDispatchEmpLess.setSort(sort);
            sort++;

            // 用增员年月的当月第一天
            if (socDispatchEmpLess.getSocEndDate() != null) {
                socDispatchEmpLess.setSocEndDate(DateKit8.getFirstDayOfMonth(socDispatchEmpLess.getSocEndDate()));
            }
            if (socDispatchEmpLess.getFundEndDate() != null) {
                socDispatchEmpLess.setFundEndDate(DateKit8.getFirstDayOfMonth(socDispatchEmpLess.getFundEndDate()));
            }

            boolean noError = false;
            CompanyDO companyDO = companyService.selectDOById(companyId, tokenUser.getSiteId());
            if(!ObjectUtils.isEmpty(companyDO)){
                socDispatchEmpLess.setAssignCompanyId(companyDO.getId());
                socDispatchEmpLess.setAssignCompanyName(companyDO.getName());
                noError = true;
            }
            // 保存员工导入记录
            socDispatchEmpLess.setNoError(noError);
            save(socDispatchEmpLess, tokenUser);
        }
        // 导入记录
        return socDispatchService.selectById(socDispatch.getId(), tokenUser.getSiteId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(SocDispatchEmpLessUpdateDTO socDispatchEmpLessUpdateDTO, TokenUser tokenUser) {
        //转DO
        SocDispatchEmpLessDO socDispatchEmpLessDO = socDispatchEmpLessUpdateDTO.to(SocDispatchEmpLessDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(socDispatchEmpLessDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... socDispatchEmpLessIds) {
        if (socDispatchEmpLessIds == null || socDispatchEmpLessIds.length == 0) {
            return 0;
        }

        Example example = new Example(SocDispatchEmpLessDO.class);
        example.and()
                .andIn("id", Arrays.asList(socDispatchEmpLessIds))
                .andEqualTo("valid", true)
                .andEqualTo("hasSend", true)
                .andEqualTo("siteId", tokenUser.getSiteId());

        int hasEndCount = socDispatchEmpLessDAO.selectCountByExample(example);
        if (hasEndCount > 0) {
            throw new ParamException("要删除的派单员工记录中存在已派单的员工,请不要删除");
        }
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) socDispatchEmpLessIds);
    }


    @Override
    public SocDispatchEmpLessVO selectById(String socDispatchEmpLessId, String siteId) {
        SocDispatchEmpLessDO socDispatchEmpLessDO = selectDOById(socDispatchEmpLessId, siteId);
        if (socDispatchEmpLessDO == null) {
            return null;
        }
        return socDispatchEmpLessDO.to(SocDispatchEmpLessVO.class);
    }

    @Override
    public List<SocDispatchEmpLessListVO> select(SocDispatchEmpLessQuery socDispatchEmpLessQuery, String siteId) {
        List<SocDispatchEmpLessDO> socDispatchEmpLessDOList = selectDO(socDispatchEmpLessQuery, siteId);
        if(CollectionUtils.isEmpty(socDispatchEmpLessDOList)) {
            return socDispatchEmpLessDOList == null ? null : new ArrayList<>();
        }
        return socDispatchEmpLessDOList.stream()
                .map(socDispatchEmpLessDO -> socDispatchEmpLessDO.to(SocDispatchEmpLessListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(SocDispatchEmpLessQuery socDispatchEmpLessQuery, String siteId) {
        Example example = buildExample(socDispatchEmpLessQuery,siteId);
        return socDispatchEmpLessDAO.selectCountByExample(example);
    }

    @Override
    public Page<SocDispatchEmpLessListVO> selectPage(SocDispatchEmpLessQuery socDispatchEmpLessQuery, String siteId) {
        Example example = buildExample(socDispatchEmpLessQuery,siteId);
        Page<SocDispatchEmpLessDO> page = socDispatchEmpLessDAO.selectPageByExample(example,
                socDispatchEmpLessQuery.getPageNo(),
                socDispatchEmpLessQuery.getPageSize());

        return page.to(SocDispatchEmpLessListVO.class);
    }

    @Override
    public SocDispatchEmpLessDO selectDOById(String socDispatchEmpLessId, String siteId) {
        return listById(socDispatchEmpLessId, siteId);
    }

    @Override
    public List<SocDispatchEmpLessDO> selectDO(SocDispatchEmpLessQuery socDispatchEmpLessQuery, String siteId) {
        Example example = buildExample(socDispatchEmpLessQuery,siteId);
        return socDispatchEmpLessDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void deleteBySocDispatchId(String siteId, String... socDispatchIds) {
        if (socDispatchIds == null || socDispatchIds.length == 0) {
            return;
        }
        Example example = new Example(SocDispatchEmpLessDO.class);
        example.and()
                .andIn("socDispatchId", Arrays.asList(socDispatchIds))
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);

        // 删除员工记录
        socDispatchEmpLessDAO.deleteByExample(example);
    }

    @Override
    public List<SocDispatchEmpLessDO> listBySocDispatchIds(String siteId, String... socDispatchIds) {
        if (socDispatchIds == null || socDispatchIds.length == 0) {
            return null;
        }
        Example example = new Example(SocDispatchEmpLessDO.class);
        example.and()
                .andIn("socDispatchId", Arrays.asList(socDispatchIds))
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);

        // 导入记录对应的员工
        return socDispatchEmpLessDAO.selectByExample(example);
    }

    @Override
    public List<SocDispatchEmpLessDO> listBySocDispatchId(String socDispatchId, String siteId) {
        Example example = new Example(SocDispatchEmpLessDO.class);
        example.and()
                .andEqualTo("socDispatchId", socDispatchId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);

        // 导入记录对应的员工
        return socDispatchEmpLessDAO.selectByExample(example);
    }

    @Override
    public List<SocDispatchEmpLessDO> listByIds(String siteId, String... ids) {
        if (ids == null || ids.length == 0) {
            return null;
        }
        Example example = new Example(SocDispatchEmpLessDO.class);
        example.and()
                .andIn("id", Arrays.asList(ids))
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);

        // 导入记录对应的员工
        return socDispatchEmpLessDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void sendBySocDispatchId(String socDispatchId, String siteId) {
        Example example = new Example(SocDispatchEmpLessDO.class);
        example.and()
                .andEqualTo("socDispatchId", socDispatchId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);

        SocDispatchEmpLessDO updateEmp = new SocDispatchEmpLessDO();
        updateEmp.setHasSend(true);

        socDispatchEmpLessDAO.updateByExampleSelective(updateEmp, example);
    }

    /**
     * 根据查询参数，构建example

     * @param socDispatchEmpLessQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(SocDispatchEmpLessQuery socDispatchEmpLessQuery, String siteId) {
        Example example = new Example(SocDispatchEmpLessDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (socDispatchEmpLessQuery.getSocDispatchId() != null) {
            example.and().andEqualTo("socDispatchId", socDispatchEmpLessQuery.getSocDispatchId());
        }
        if (socDispatchEmpLessQuery.getYear() != null) {
            example.and().andEqualTo("year", socDispatchEmpLessQuery.getYear());
        }
        if (socDispatchEmpLessQuery.getMonth() != null) {
            example.and().andEqualTo("month", socDispatchEmpLessQuery.getMonth());
        }
        if (socDispatchEmpLessQuery.getName() != null) {
            example.and().andLike("name", "%" + socDispatchEmpLessQuery.getName() + "%");
        }
        if (socDispatchEmpLessQuery.getPhone() != null) {
            example.and().andEqualTo("phone", socDispatchEmpLessQuery.getPhone());
        }
        if (socDispatchEmpLessQuery.getIdCard() != null) {
            example.and().andEqualTo("idCard", socDispatchEmpLessQuery.getIdCard());
        }
        if (socDispatchEmpLessQuery.getSocCityName() != null) {
            example.and().andEqualTo("socCityName", socDispatchEmpLessQuery.getSocCityName());
        }
        if (socDispatchEmpLessQuery.getSocCityId() != null) {
            example.and().andEqualTo("socCityId", socDispatchEmpLessQuery.getSocCityId());
        }
        if (socDispatchEmpLessQuery.getAssignCompanyId() != null) {
            example.and().andEqualTo("assignCompanyId", socDispatchEmpLessQuery.getAssignCompanyId());
        }
        if (socDispatchEmpLessQuery.getAssignCompanyName() != null) {
            example.and().andEqualTo("assignCompanyName", socDispatchEmpLessQuery.getAssignCompanyName());
        }
        if (socDispatchEmpLessQuery.getSocEndDateStart() != null &&
                socDispatchEmpLessQuery.getSocEndDateEnd() != null) {
            example.and().andBetween("socEndDate", socDispatchEmpLessQuery.getSocEndDateStart(),
                    socDispatchEmpLessQuery.getSocEndDateEnd());
        }
        if (socDispatchEmpLessQuery.getFundEndDateStart() != null &&
                socDispatchEmpLessQuery.getFundEndDateEnd() != null) {
            example.and().andBetween("fundEndDate", socDispatchEmpLessQuery.getFundEndDateStart(),
                    socDispatchEmpLessQuery.getFundEndDateEnd());
        }
        if (socDispatchEmpLessQuery.getQuitDateStart() != null &&
                socDispatchEmpLessQuery.getQuitDateEnd() != null) {
            example.and().andBetween("quitDate", socDispatchEmpLessQuery.getQuitDateStart(),
                    socDispatchEmpLessQuery.getQuitDateEnd());
        }
        if (socDispatchEmpLessQuery.getReasonQuit() != null) {
            example.and().andEqualTo("reasonQuit", socDispatchEmpLessQuery.getReasonQuit());
        }
        if (socDispatchEmpLessQuery.getRemake() != null) {
            example.and().andEqualTo("remake", socDispatchEmpLessQuery.getRemake());
        }
        if (socDispatchEmpLessQuery.getStatus() != null) {
            example.and().andEqualTo("status", socDispatchEmpLessQuery.getStatus());
        }
        if (socDispatchEmpLessQuery.getHasSend() != null) {
            example.and().andEqualTo("hasSend", socDispatchEmpLessQuery.getHasSend());
        }
        if (socDispatchEmpLessQuery.getHasReceive() != null) {
            example.and().andEqualTo("hasReceive", socDispatchEmpLessQuery.getHasReceive());
        }
        if (socDispatchEmpLessQuery.getNoError() != null) {
            example.and().andEqualTo("noError", socDispatchEmpLessQuery.getNoError());
        }
        if (socDispatchEmpLessQuery.getCompanyId() != null) {
            example.and().andEqualTo("companyId", socDispatchEmpLessQuery.getCompanyId());
        }
        if (socDispatchEmpLessQuery.getSort() != null) {
            example.and().andEqualTo("sort", socDispatchEmpLessQuery.getSort());
        }
        example.orderBy("sort").asc();
//        // 排序
//        ExampleKit.setExampleOrder(example,socDispatchEmpLessQuery.getOrders());
        return example;
    }
}




